<?php
/*
# ------------------------------------------------------------------------
# JA Teline III - Version 1.3 - Licence Owner jSharing.COM
# ------------------------------------------------------------------------
# Copyright (C) Lifetime Joomla Just for Sharing, Ltd. All Rights Reserved.
# @license - Copyrighted Commercial Software
# Author: Joomla Just for Sharing
# Websites:  http://jsharing.com -  http://jsharing.net
# This file may not be redistributed in whole or significant part.
# ------------------------------------------------------------------------
*/

// no direct access
defined ( '_JEXEC' ) or die ( 'Restricted access' );
if (! defined ( '_JA_NEWS2_' )) {
	define ( '_JA_NEWS2_', 1 );
	
	require_once (JPATH_SITE . '/components/com_content/helpers/route.php');
	
	class modJaNews2Helper extends JObject {
		var $_module = null;
		var $_params = null;
		var $_usersetting = array ();
		
		function __construct($module, $params = null) {
			$this->_module = $module;
			$this->_params = $params ? $params : new JParameter ( '' );
			$this->loadUserSetting ();
		}
		
		function replaceImage(&$row, $align, $autoresize, $maxchars, $showimage, $width = 0, $height = 0, $hiddenClasses = '') {
			global $database, $_MAMBOTS, $current_charset;
			$regex = '#<\s*img [^\>]*src\s*=\s*(["\'])(.*?)\1#im';
			
			preg_match ( $regex, $row->introtext, $matches );
			if (! count ( $matches ))
				preg_match ( $regex, $row->fulltext, $matches );
			$images = (count ( $matches )) ? $matches : array ();
			$image = '';
			if (count ( $images ))
				$image = trim ( $images [2] );
			$align = $align ? "align=\"$align\"" : "";
			if ($image && $showimage) {
				if ($autoresize && function_exists ( 'imagecreatetruecolor' ) && ($image1 = $this->processImage ( $image, $width, $height ))) {
					$image = "<img src=\"" . $image1 . "\" alt=\"{$row->title}\" $align />";
				} else {
					$width = $width ? "width=\"$width\"" : "";
					$height = $height ? "height=\"$height\"" : "";
					$image = "<img src=\"" . $image . "\" alt=\"{$row->title}\" $width $height $align />";
				}
			} else
				$image = '';
			
			$regex1 = "/\<img[^\>]*>/";
			$row->introtext = preg_replace ( $regex1, '', $row->introtext );
			$regex1 = "/<div class=\"mosimage\".*<\/div>/";
			$row->introtext = preg_replace ( $regex1, '', $row->introtext );
			$row->introtext = trim ( $row->introtext );
			$row->introtext1 = $row->introtext;
			if ($maxchars && strlen ( $row->introtext ) > $maxchars) {
				$doc = JDocument::getInstance ();
				if (function_exists ( 'mb_substr' )) {
					$row->introtext1 = SmartTrim::mb_trim ( $row->introtext, 0, $maxchars, $doc->_charset );
				} else {
					$row->introtext1 = SmartTrim::trim ( $row->introtext, 0, $maxchars );
				}
			}
			// clean up globals
			return $image;
		}
		
		function processImage($img, $width, $height) {
			if (! $img)
				return '';
			$img = str_replace ( JURI::base (), '', $img );
			$img = rawurldecode ( $img );
			$imagesurl = (file_exists ( JPATH_SITE . '/' . $img )) ? $this->jaResize ( $img, $width, $height ) : '';
			return $imagesurl;
		}
		
		function jaResize($image, $max_width, $max_height, $crop = 1) {
			$path = JPATH_SITE;
			$imgInfo = getimagesize ( $path . '/' . $image );
			$width = $imgInfo [0];
			$height = $imgInfo [1];
			if (! $max_width && ! $max_height) {
				$max_width = $width;
				$max_height = $height;
			} else {
				if (! $max_width)
					$max_width = 1000;
				if (! $max_height)
					$max_height = 1000;
			}
			$x_ratio = $max_width / $width;
			$y_ratio = $max_height / $height;
			
			$dst = new stdClass ( );
			$src = new stdClass ( );
			$src->y = $src->x = 0;
			$dst->y = $dst->x = 0;
			if ($max_width > $width)
				$max_width = $width;
			if ($max_height > $height)
				$max_height = $height;
			
			if ($max_width == $width && $max_height == $height)
				return $image;
			
			if ($crop) {
				$dst->w = $max_width;
				$dst->h = $max_height;
				if (($width <= $max_width) && ($height <= $max_height)) {
					$src->w = $max_width;
					$src->h = $max_height;
				} else {
					if ($x_ratio < $y_ratio) {
						$src->w = ceil ( $max_width / $y_ratio );
						$src->h = $height;
					} else {
						$src->w = $width;
						$src->h = ceil ( $max_height / $x_ratio );
					}
				}
				$src->x = floor ( ($width - $src->w) / 2 );
				$src->y = floor ( ($height - $src->h) / 2 );
			} else {
				$src->w = $width;
				$src->h = $height;
				if (($width <= $max_width) && ($height <= $max_height)) {
					$dst->w = $width;
					$dst->h = $height;
				} else if (($x_ratio * $height) < $max_height) {
					$dst->h = ceil ( $x_ratio * $height );
					$dst->w = $max_width;
				} else {
					$dst->w = ceil ( $y_ratio * $width );
					$dst->h = $max_height;
				}
			}
			
			$ext = strtolower ( substr ( strrchr ( $image, '.' ), 1 ) ); // get the file extension
			$rzname = strtolower ( substr ( $image, 0, strpos ( $image, '.' ) ) ) . "_{$dst->w}_{$dst->h}.{$ext}"; // get the file extension
			//
			$resized = $path . '/images/resized/' . $rzname;
			if (file_exists ( $resized )) {
				$smallImg = getimagesize ( $resized );
				if (($smallImg [0] <= $dst->w && $smallImg [1] == $dst->h) || ($smallImg [1] <= $dst->h && $smallImg [0] == $dst->w)) {
					return "images/resized/" . $rzname;
				}
			}
			if (! file_exists ( $path . '/images/resized/' ) && ! mkdir ( $path . '/images/resized/', 0755 ))
				return '';
			$folders = explode ( '/', strtolower ( $image ) );
			$tmppath = $path . '/images/resized/';
			for($i = 0; $i < count ( $folders ) - 1; $i ++) {
				if (! file_exists ( $tmppath . $folders [$i] ) && ! mkdir ( $tmppath . $folders [$i], 0755 ))
					return '';
				$tmppath = $tmppath . $folders [$i] . '/';
			}
			
			switch ($imgInfo [2]) {
				case 1 :
					$im = imagecreatefromgif ( $path . '/' . $image );
					break;
				case 2 :
					$im = imagecreatefromjpeg ( $path . '/' . $image );
					break;
				case 3 :
					$im = imagecreatefrompng ( $path . '/' . $image );
					break;
				default :
					return '';
					break;
			}
			
			$newImg = imagecreatetruecolor ( $dst->w, $dst->h );
			
			/* Check if this image is PNG or GIF, then set if Transparent*/
			if (($imgInfo [2] == 1) or ($imgInfo [2] == 3)) {
				imagealphablending ( $newImg, false );
				imagesavealpha ( $newImg, true );
				$transparent = imagecolorallocatealpha ( $newImg, 255, 255, 255, 127 );
				imagefilledrectangle ( $newImg, 0, 0, $dst->w, $dst->h, $transparent );
			}
			imagecopyresampled ( $newImg, $im, $dst->x, $dst->y, $src->x, $src->y, $dst->w, $dst->h, $src->w, $src->h );
			
			//Generate the file, and rename it to $newfilename
			switch ($imgInfo [2]) {
				case 1 :
					imagegif ( $newImg, $resized );
					break;
				case 2 :
					imagejpeg ( $newImg, $resized, 90 );
					break;
				case 3 :
					imagepng ( $newImg, $resized );
					break;
				default :
					return '';
					break;
			}
			
			return "images/resized/" . $rzname;
		}
		
		function calModStyle($cols) {
			$modules = array ();
			switch ($cols) {
				case 0 :
					return null;
					break;
				case 1 :
					$modules [0] ['class'] = "";
					$modules [0] ['width'] = "100%";
					$modules [0] ['subwidth'] = "100%";
					break;
				case 2 :
					$modules [0] ['class'] = "-left";
					$modules [0] ['width'] = "49.9%";
					$modules [0] ['subwidth'] = "95%";
					$modules [1] ['class'] = "-right";
					$modules [1] ['width'] = "49.9%";
					$modules [1] ['subwidth'] = "95%";
					break;
				default :
					
					$width1 = round ( 99.6 / ($cols - 0.1), 2 );
					$width2 = round ( (99.6 - $width1 * ($cols - 2)) / 2, 2 );
					
					for($i = 1; $i < $cols - 1; $i ++) {
						$modules [$i] ['class'] = "-center";
						$modules [$i] ['width'] = $width1 . "%";
						$modules [$i] ['subwidth'] = "90%";
					}
					$modules [0] ['class'] = "-left";
					$modules [0] ['width'] = $width2 . "%";
					$modules [0] ['subwidth'] = "95%";
					$modules [$cols - 1] ['class'] = "-right";
					$modules [$cols - 1] ['width'] = $width2 . "%";
					$modules [$cols - 1] ['subwidth'] = "95%";
					break;
			}
			return $modules;
		}
		
		function unhtmlentities($string) {
			$trans_tbl = array ("&lt;" => "<", "&gt;" => ">", "&amp;" => "&" );
			return strtr ( $string, $trans_tbl );
		}
		
		function getList($catorsec, $catid, $items, $ordering, $showcontentfrontpage = false) {
			global $mainframe;
			
			$db = & JFactory::getDBO ();
			$user = & JFactory::getUser ();
			$aid = $user->get ( 'aid', 0 );
			
			$contentConfig = &JComponentHelper::getParams ( 'com_content' );
			$noauth = ! $contentConfig->get ( 'shownoauth' );
			
			jimport ( 'joomla.utilities.date' );
			$date = new JDate ( );
			$now = $date->toMySQL ();
			
			$nullDate = $db->getNullDate ();
			
			// query to determine article count
			$query = 'SELECT a.*,u.name as creater,cc.description as catdesc, cc.title as cattitle,s.description as secdesc, s.title as sectitle,' . ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END as slug,' . ' CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END as catslug,' . ' CASE WHEN CHAR_LENGTH(s.alias) THEN CONCAT_WS(":", s.id, s.alias) ELSE s.id END as secslug' . ' FROM #__content AS a' . ' INNER JOIN #__categories AS cc ON cc.id = a.catid' . ' INNER JOIN #__sections AS s ON s.id = a.sectionid' . ' left JOIN #__users AS u ON a.created_by = u.id';
			$query .= ' WHERE a.state = 1 ' . ($noauth ? ' AND a.access <= ' . ( int ) $aid . ' AND cc.access <= ' . ( int ) $aid . ' AND s.access <= ' . ( int ) $aid : '') . ' AND (a.publish_up = ' . $db->Quote ( $nullDate ) . ' OR a.publish_up <= ' . $db->Quote ( $now ) . ' ) ' . ' AND (a.publish_down = ' . $db->Quote ( $nullDate ) . ' OR a.publish_down >= ' . $db->Quote ( $now ) . ' )' . (($catorsec) ? "\n AND cc.id=" . ( int ) $catid : ' AND s.id=' . ( int ) $catid) . ' AND cc.section = s.id' . ' AND cc.published = 1' . ' AND s.published = 1';
			if (! $showcontentfrontpage) {
				$query .= ' AND a.id not in (SELECT content_id FROM #__content_frontpage )';
			}
			
			//$query .= ' ORDER BY a.created DESC' ;
			$query .= ' ORDER BY a.' . $ordering;
			
			$db->setQuery ( $query, 0, $items );
			$rows = $db->loadObjectList ();
			global $mainframe;
			JPluginHelper::importPlugin ( 'content' );
			$dispatcher = & JDispatcher::getInstance ();
			$params = & $mainframe->getParams ( 'com_content' );
			$limitstart = JRequest::getVar ( 'limitstart', 0, '', 'int' );
			
			for($i = 0; $i < count ( $rows ); $i ++) {
				$rows [$i]->text = $rows [$i]->introtext;
				$results = $dispatcher->trigger ( 'onPrepareContent', array (& $rows [$i], & $params, $limitstart ) );
				$rows [$i]->introtext = $rows [$i]->text;
			}
			return $rows;
		}
		
		function getCatIDs($secid) {
			$db = & JFactory::getDBO ();
			//Get from user setting
			$catids = $this->getUserSetting ( $secid, 'categories' );
			if ($catids && count ( $catids ))
				return $catids;
				
			//Get default
			$limit = ( int ) $this->get ( 'cols', 2 );
			$query = "SELECT id FROM #__categories WHERE published = 1 and section=" . ( int ) $secid . " order by ordering";
			$db->setQuery ( $query, 0, $limit );
			$c = $db->loadObjectList ();
			$catids = array ();
			foreach ( $c as $_c )
				$catids [] = $_c->id;
			return $catids;
		}
		
		function getGroupList($secid, $items, $ordering, $showcontentfrontpage = false) {
			global $mainframe;
			$db = & JFactory::getDBO ();
			$user = & JFactory::getUser ();
			$aid = $user->get ( 'aid', 0 );
			
			$contentConfig = &JComponentHelper::getParams ( 'com_content' );
			$noauth = ! $contentConfig->get ( 'shownoauth' );
			
			//Get category ids:
			$catids = $this->loadCategories ( $secid );
			
			jimport ( 'joomla.utilities.date' );
			$date = new JDate ( );
			$now = $date->toMySQL ();
			
			$nullDate = $db->getNullDate ();
			$result = array ();
			$j = 0;
			foreach ( $catids as $cat ) {
				$catid = $catids[$j]->category->id;
				// query to determine article count
				$query = 'SELECT a.*,u.name as creater,cc.description as catdesc, cc.title as cattitle,s.description as secdesc, s.title as sectitle,' . ' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END as slug,' . ' CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END as catslug,' . ' CASE WHEN CHAR_LENGTH(s.alias) THEN CONCAT_WS(":", s.id, s.alias) ELSE s.id END as secslug' . ' FROM #__content AS a' . ' INNER JOIN #__categories AS cc ON cc.id = a.catid' . ' INNER JOIN #__sections AS s ON s.id = a.sectionid' . ' left JOIN #__users AS u ON a.created_by = u.id';
				$query .= ' WHERE a.state = 1 ' . ($noauth ? ' AND a.access <= ' . ( int ) $aid . ' AND cc.access <= ' . ( int ) $aid . ' AND s.access <= ' . ( int ) $aid : '') . ' AND (a.publish_up = ' . $db->Quote ( $nullDate ) . ' OR a.publish_up <= ' . $db->Quote ( $now ) . ' ) ' . ' AND (a.publish_down = ' . $db->Quote ( $nullDate ) . ' OR a.publish_down >= ' . $db->Quote ( $now ) . ' )' . "\n AND cc.id=" . ( int ) $catid . ' AND cc.section = s.id' . ' AND cc.published = 1' . ' AND s.published = 1';
				if (! $showcontentfrontpage) {
					$query .= ' AND a.id not in (SELECT content_id FROM #__content_frontpage )';
				}
				
				//$query .= ' ORDER BY a.created DESC' ;
				$query .= ' ORDER BY a.' . $ordering;
				
				$db->setQuery ( $query, 0, $items );
				$rows = $db->loadObjectList ();
				global $mainframe;
				JPluginHelper::importPlugin ( 'content' );
				$dispatcher = & JDispatcher::getInstance ();
				$params = & $mainframe->getParams ( 'com_content' );
				$limitstart = JRequest::getVar ( 'limitstart', 0, '', 'int' );
				
				for($i = 0; $i < count ( $rows ); $i ++) {
					$rows [$i]->text = $rows [$i]->introtext;
					$results = $dispatcher->trigger ( 'onPrepareContent', array (& $rows [$i], & $params, $limitstart ) );
					$rows [$i]->introtext = $rows [$i]->text;
				}
				
				$catids[$j]->contents = $rows;
				$j++;
			}
			return $catids;
		}
		
		function getHLNews($items) {
			$db = & JFactory::getDBO ();
			$contentConfig = &JComponentHelper::getParams ( 'com_content' );
			$noauth = ! $contentConfig->get ( 'shownoauth' );
			$user = & JFactory::getUser ();
			$aid = $user->get ( 'aid', 0 );
			
			jimport ( 'joomla.utilities.date' );
			$date = new JDate ( );
			$now = $date->toMySQL ();
			
			$nullDate = $db->getNullDate ();
			$query = "SELECT a.*," . "\n CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(':', a.id, a.alias) ELSE a.id END as slug," . "\n CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(':', cc.id, cc.alias) ELSE cc.id END as catslug" . "\n FROM #__content AS a" . "\n INNER JOIN #__content_frontpage AS f ON f.content_id = a.id" . "\n INNER JOIN #__categories AS cc ON cc.id = a.catid" . "\n WHERE ( a.state = 1 AND a.sectionid > 0 " . ' AND (a.publish_up = ' . $db->Quote ( $nullDate ) . ' OR a.publish_up <= ' . $db->Quote ( $now ) . ' ) ' . ' AND (a.publish_down = ' . $db->Quote ( $nullDate ) . ' OR a.publish_down >= ' . $db->Quote ( $now ) . ' )' . ($noauth ? ' AND a.access <= ' . ( int ) $aid . ' AND cc.access <= ' . ( int ) $aid : '') . "\n AND cc.published = 1 )" . "\n ORDER BY f.ordering ASC";
			$db->setQuery ( $query, 0, $items );
			$news = $db->loadObjectList ();
			
			global $mainframe;
			JPluginHelper::importPlugin ( 'content' );
			$dispatcher = & JDispatcher::getInstance ();
			$params = & $mainframe->getParams ( 'com_content' );
			$limitstart = JRequest::getVar ( 'limitstart', 0, '', 'int' );
			
			for($i = 0; $i < count ( $news ); $i ++) {
				$news [$i]->text = $news [$i]->introtext;
				$results = $dispatcher->trigger ( 'onPrepareContent', array (& $news [$i], & $params, $limitstart ) );
				$news [$i]->introtext = $news [$i]->text;
			}
			
			return $news;
		}
		
		function getFile($name, $modPath, $tmplPath) {
			if (file_exists ( JPATH_SITE . DS . $tmplPath . $name )) {
				return $tmplPath . $name;
			}
			return $modPath . $name;
		}
		
		function getAllCatIds($catorsec) {
			$db = & JFactory::getDBO ();
			if ($catorsec) {
				$query = "SELECT id FROM #__categories WHERE published = 1;";
			} else {
				$query = "SELECT id FROM #__sections WHERE published = 1;";
			}
			$db->setQuery ( $query );
			$c = $db->loadObjectList ();
			$catids = array ();
			foreach ( $c as $_c )
				$catids [] = $_c->id;
			return $catids;
		}
		
		function getAllSectionIds() {
			$db = & JFactory::getDBO ();
			$query = "SELECT id FROM #__sections WHERE published = 1;";
			$db->setQuery ( $query );
			$c = $db->loadObjectList ();
			$catids = array ();
			foreach ( $c as $_c )
				$catids [] = $_c->id;
			return $catids;
		}
		
		function getAllCategoriesBySection($sectionid) {
			$db = & JFactory::getDBO ();
			$query = "SELECT id,title FROM #__categories WHERE section = $sectionid;";
			
			$db->setQuery ( $query );
			$cats = $db->loadObjectList ();
			
			return $cats;
		}
		
		function getModuleParameters($modid) {
			$db = & JFactory::getDBO ();
			$query = "SELECT params FROM #__modules WHERE id = $modid;";
			$db->setQuery ( $query );
			return $db->loadResult ();
		}
		
		function getItemid($sectionid) {
			$contentConfig = &JComponentHelper::getParams ( 'com_content' );
			$noauth = ! $contentConfig->get ( 'shownoauth' );
			$user = & JFactory::getUser ();
			$aid = $user->get ( 'aid', 0 );
			$db = & JFactory::getDBO ();
			$query = "SELECT id FROM #__menu WHERE `link` like '%option=com_content%view=section%id=$sectionid%'" . ' AND published = 1' . ($noauth ? ' AND access <= ' . ( int ) $aid : '');
			
			$db->setQuery ( $query );
			return $db->loadResult ();
		}
		
		function loadUserSetting() {
			if (class_exists ( 'JAUserSettingHelper' )) {
				$this->_usersetting = JAUserSettingHelper::getSetting ( $this->_module->module );
			}
		}
		
		function _load() {
			$catid = trim ( $this->get ( 'secids' ) );
			$showheadline = intval ( trim ( $this->get ( 'showheadline', 0 ) ) );
			$cols = intval ( trim ( $this->get ( 'cols', 2 ) ) );
			$ordering = trim ( $this->get ( 'ordering', 'created desc' ) );
			$showcontentfrontpage = intval ( trim ( $this->get ( 'showcontentfrontpage', 1 ) ) );
			$introitems = intval ( trim ( $this->get ( 'introitems', 1 ) ) );
			$linkitems = intval ( trim ( $this->get ( 'linkitems', 0 ) ) );
			$mainframe = &JFactory::getApplication ( 'site' );
			//echo '<script type="text/javascript" src="modules/mod_janews/ja.news/ja.news.js"></script>';
			

			$contents = $themes = array ();
			$this->_sections = $this->loadSections ();
			if (! count ( $this->_sections ))
				return;
			$i = 0;
			foreach ( $this->_sections as $section ) {
				$sid = $section->section->id;
				$s_introitems = $this->getUserSetting ( $sid, 'introitems', $introitems );
				$s_linkitems = $this->getUserSetting ( $sid, 'linkitems', $linkitems );
				$this->_sections [$i]->categories = $this->getGroupList ( $sid, $s_linkitems + $s_introitems, $ordering, $showcontentfrontpage );
				$i ++;
			}
		}
		
		function loadSections() {
			$sections = array ();
			$secs = trim ( $this->get ( 'sections' ) );
			$where = '';
			$themes = array ();
			if ($secs) {
				$secs = preg_split ( '/[\n,]|<br \/>/', $secs );
				$secids = array ();
				for($i = 0; $i < count ( $secs ); $i ++) {
					$temp = split ( ':', $secs [$i] );
					if (isset ( $temp [0] ))
						$secid = $temp [0];
					if ($secid) {
						$secids [] = $secid;
						$themes [$secid] = isset ( $temp [1] ) ? $temp [1] : '';
					}
				}
				$where .= " AND `id` in (" . implode ( ',', $secids ) . ")";
			}
			$db = & JFactory::getDBO ();
			$query = "SELECT id, title, `description`, CASE WHEN CHAR_LENGTH(s.alias) THEN CONCAT_WS(\":\", s.id, s.alias) ELSE s.id END as slug FROM #__sections s WHERE published = 1" . $where;
			$db->setQuery ( $query );
			$rows = $db->loadObjectList ( 'id' );
			if ($rows && count ( $rows )) {
				$rows_id = array_keys ( $rows );
				if (! $secs)
					$secids = $rows_id;
				foreach ( $secids as $sid ) {
					if (! in_array ( $sid, $rows_id ))
						continue;
					$obj = new stdclass ( );
					$obj->section = $rows [$sid];
					$obj->theme = isset ( $themes [$sid] ) ? $themes [$sid] : '';
					$sections [] = $obj;
				}
			}
			return $sections;
		}
		
		function loadCategories($sid) {
			$categories = array ();
			$catids = $this->getUserSetting ( $sid, 'categories' );
			
			$where = '';
			$limit = 0;
			if ($catids) {
				if (is_array ( $catids ))
					$where .= " AND `id` in (" . implode ( ',', $catids ) . ")";
			} else {
				if (is_array ( $this->getUserSetting ( $sid ) ))
					$where = " AND 0";
				else
					$limit = ( int ) $this->get ( 'cols', 2 );
			}
			
			$db = & JFactory::getDBO ();
			$query = "SELECT `id`, `title`, `description`, CASE WHEN CHAR_LENGTH(`alias`) THEN CONCAT_WS(\":\", `id`, `alias`) ELSE `id` END as `slug` FROM `#__categories` s WHERE published = 1 and section=" . ( int ) $sid . $where;
			$db->setQuery ( $query, 0, $limit );
			$rows = $db->loadObjectList ( 'id' );
			foreach ( $rows as $cid => $row ) {
				$obj = new stdclass ( );
				$obj->category = $row;
				$categories [] = $obj;
			}
			return $categories;
		}
		
		function getUserSetting($sid, $name = null, $default = null) {
			$group = "sid:$sid";
			if (! $name) {
				if (isset ( $this->_usersetting [$group] ))
					return $this->_usersetting [$group];
				return $default;
			}
			if (isset ( $this->_usersetting [$group] ) && isset ( $this->_usersetting [$group] [$name] ))
				return $this->_usersetting [$group] [$name];
			if (isset ( $this->_usersetting [$group] ) && isset ( $this->_usersetting [$group] ['params'] ) && isset ( $this->_usersetting [$group] ['params'] [$name] ))
				return $this->_usersetting [$group] ['params'] [$name];
			return $this->get ( $name, $default );
		}
		
		function get($name, $default = null) {
			return $this->_params->get ( $name, $default );
		}
	}
}
if (! class_exists ( 'SmartTrim' )) {
	class SmartTrim {
		/*
      $hiddenClasses: Class that have property display: none or invisible.
    */
		function mb_trim($strin, $pos = 0, $len = 10000, $hiddenClasses = '', $encoding = 'utf-8') {
			mb_internal_encoding ( $encoding );
			$strout = trim ( $strin );
			
			$pattern = '/(<[^>]*>)/';
			$arr = preg_split ( $pattern, $strout, - 1, PREG_SPLIT_DELIM_CAPTURE );
			$left = $pos;
			$length = $len;
			$strout = '';
			for($i = 0; $i < count ( $arr ); $i ++) {
				$arr [$i] = trim ( $arr [$i] );
				if ($arr [$i] == '')
					continue;
				if ($i % 2 == 0) {
					if ($left > 0) {
						$t = $arr [$i];
						$arr [$i] = mb_substr ( $t, $left );
						$left -= (mb_strlen ( $t ) - mb_strlen ( $arr [$i] ));
					}
					
					if ($left <= 0) {
						if ($length > 0) {
							$t = $arr [$i];
							$arr [$i] = mb_substr ( $t, 0, $length );
							$length -= mb_strlen ( $arr [$i] );
							if ($length <= 0) {
								$arr [$i] .= '...';
							}
						
						} else {
							$arr [$i] = '';
						}
					}
				} else {
					if (SmartTrim::isHiddenTag ( $arr [$i], $hiddenClasses )) {
						if ($endTag = SmartTrim::getCloseTag ( $arr, $i )) {
							while ( $i < $endTag )
								$strout .= $arr [$i ++] . "\n";
						}
					}
				}
				$strout .= $arr [$i] . "\n";
			}
			//echo $strout;  
			return SmartTrim::toString ( $arr, $len );
		}
		
		function trim($strin, $pos = 0, $len = 10000, $hiddenClasses = '') {
			$strout = trim ( $strin );
			
			$pattern = '/(<[^>]*>)/';
			$arr = preg_split ( $pattern, $strout, - 1, PREG_SPLIT_DELIM_CAPTURE );
			$left = $pos;
			$length = $len;
			$strout = '';
			for($i = 0; $i < count ( $arr ); $i ++) {
				$arr [$i] = trim ( $arr [$i] );
				if ($arr [$i] == '')
					continue;
				if ($i % 2 == 0) {
					if ($left > 0) {
						$t = $arr [$i];
						$arr [$i] = substr ( $t, $left );
						$left -= (strlen ( $t ) - strlen ( $arr [$i] ));
					}
					
					if ($left <= 0) {
						if ($length > 0) {
							$t = $arr [$i];
							$arr [$i] = substr ( $t, 0, $length );
							$length -= strlen ( $arr [$i] );
							if ($length <= 0) {
								$arr [$i] .= '...';
							}
						
						} else {
							$arr [$i] = '';
						}
					}
				} else {
					if (SmartTrim::isHiddenTag ( $arr [$i], $hiddenClasses )) {
						if ($endTag = SmartTrim::getCloseTag ( $arr, $i )) {
							while ( $i < $endTag )
								$strout .= $arr [$i ++] . "\n";
						}
					}
				}
				$strout .= $arr [$i] . "\n";
			}
			//echo $strout;  
			return SmartTrim::toString ( $arr, $len );
		}
		
		function isHiddenTag($tag, $hiddenClasses = '') {
			//By pass full tag like img
			if (substr ( $tag, - 2 ) == '/>')
				return false;
			if (in_array ( SmartTrim::getTag ( $tag ), array ('script', 'style' ) ))
				return true;
			if (preg_match ( '/display\s*:\s*none/', $tag ))
				return true;
			if ($hiddenClasses && preg_match ( '/class\s*=[\s"\']*(' . $hiddenClasses . ')[\s"\']*/', $tag ))
				return true;
		}
		
		function getCloseTag($arr, $openidx) {
			$tag = trim ( $arr [$openidx] );
			if (! $openTag = SmartTrim::getTag ( $tag ))
				return 0;
			
			$endTag = "</$openTag>";
			$endidx = $openidx + 1;
			$i = 1;
			while ( $endidx < count ( $arr ) ) {
				if (trim ( $arr [$endidx] ) == $endTag)
					$i --;
				if (SmartTrim::getTag ( $arr [$endidx] ) == $openTag)
					$i ++;
				if ($i == 0)
					return $endidx;
				$endidx ++;
			}
			return 0;
		}
		
		function getTag($tag) {
			if (preg_match ( '/\A<([^\/>]*)\/>\Z/', trim ( $tag ), $matches ))
				return ''; //full tag
			if (preg_match ( '/\A<([^ \/>]*)([^>]*)>\Z/', trim ( $tag ), $matches )) {
				//echo "[".strtolower($matches[1])."]";
				return strtolower ( $matches [1] );
			}
			//if (preg_match ('/<([^ \/>]*)([^\/>]*)>/', trim($tag), $matches)) return strtolower($matches[1]);
			return '';
		}
		
		function toString($arr, $len) {
			$i = 0;
			$stack = new JAStack ( );
			$length = 0;
			while ( $i < count ( $arr ) ) {
				$tag = trim ( $arr [$i ++] );
				if ($tag == '')
					continue;
				if (SmartTrim::isCloseTag ( $tag )) {
					if ($ltag = $stack->getLast ()) {
						if ('</' . SmartTrim::getTag ( $ltag ) . '>' == $tag)
							$stack->pop ();
						else
							$stack->push ( $tag );
					}
				} else if (SmartTrim::isOpenTag ( $tag )) {
					$stack->push ( $tag );
				} else if (SmartTrim::isFullTag ( $tag )) {
					//echo "[TAG: $tag, $length, $len]\n";
					if ($length < $len)
						$stack->push ( $tag );
				} else {
					$length += strlen ( $tag );
					$stack->push ( $tag );
				}
			}
			
			return $stack->toString ();
		}
		
		function isOpenTag($tag) {
			if (preg_match ( '/\A<([^\/>]+)\/>\Z/', trim ( $tag ), $matches ))
				return false; //full tag
			if (preg_match ( '/\A<([^ \/>]+)([^>]*)>\Z/', trim ( $tag ), $matches ))
				return true;
			return false;
		}
		
		function isFullTag($tag) {
			//echo "[Check full: $tag]\n";
			if (preg_match ( '/\A<([^\/>]*)\/>\Z/', trim ( $tag ), $matches ))
				return true; //full tag
			return false;
		}
		
		function isCloseTag($tag) {
			if (preg_match ( '/<\/(.*)>/', $tag ))
				return true;
			return false;
		}
	}
	
	class JAStack {
		var $_arr = null;
		function JAStack() {
			$this->_arr = array ();
		}
		
		function push($item) {
			$this->_arr [count ( $this->_arr )] = $item;
		}
		function pop() {
			if (! $c = count ( $this->_arr ))
				return null;
			$ret = $this->_arr [$c - 1];
			unset ( $this->_arr [$c - 1] );
			return $ret;
		}
		function getLast() {
			if (! $c = count ( $this->_arr ))
				return null;
			return $this->_arr [$c - 1];
		}
		function toString() {
			$output = '';
			foreach ( $this->_arr as $item ) {
				$output .= $item . "\n";
			}
			return $output;
		}
	}
}

